Cursor HITL: use Cursor's native approval (drop readOnlyHint + skip our elicitation)#40
Open
pragati-agrawal-glean wants to merge 2 commits into
Open
Cursor HITL: use Cursor's native approval (drop readOnlyHint + skip our elicitation)#40pragati-agrawal-glean wants to merge 2 commits into
pragati-agrawal-glean wants to merge 2 commits into
Conversation
Cursor 3.12.x only renders a server-initiated elicitation on its attended tool-call lane. run_tool marked readOnlyHint:true lands on Cursor's auto-run lane, where the HITL approval elicitation is silently dropped — producing a 5-minute silent hang and a fail-closed timeout with no approval banner. Cursor also strips tool `annotations` on ingest (and has zero references to readOnlyHint in its bundle), so the hint never suppressed a native prompt there anyway. Thread the client identity into runToolAnnotations and omit readOnlyHint when the client is Cursor (clientInfo.name starts with "cursor"), keeping run_tool on the interactive lane so the banner renders. Claude Code is unaffected: it renders elicitation regardless of lane, and the hint still suppresses its native prompt. Temporary until the Cursor-side rendering regression is fixed upstream. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pragati-agrawal-glean
force-pushed
the
fix/cursor-disable-readonlyhint-hitl
branch
from
July 21, 2026 17:37
f8d8136 to
0d6750d
Compare
pragati-agrawal-glean
marked this pull request as ready for review
July 21, 2026 17:37
pragati-agrawal-glean
requested review from
eshwar-sundar-glean,
garvit-scio,
mohit-gupta-glean and
swarup-padhi-glean
as code owners
July 21, 2026 17:37
swarup-padhi-glean
approved these changes
Jul 21, 2026
swarup-padhi-glean
left a comment
Contributor
There was a problem hiding this comment.
Can we also have a demo video in the PR?
Pairs with omitting run_tool's readOnlyHint for Cursor. With the hint gone, Cursor shows its own native run-tool approval before executing run_tool, so our server-initiated elicitation is a redundant second gate — and Cursor 3.12.x silently drops it on the auto-run lane, hanging for the full HITL timeout. Skip the elicitation gate for Cursor (add !isCursorClient to the gate) and let its native prompt be the single approval; the tool then executes directly. Claude Code is unchanged: keeps readOnlyHint and our elicitation remains its gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
swarup-padhi-glean
approved these changes
Jul 22, 2026
Contributor
Author
|
Demo video after making the change |
Contributor
|
Hey @pragati-agrawal-glean we will need to raise & investigate why we are having cursor's hitl for find_skills |
eshwar-sundar-glean
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix the Cursor HITL approval flow
Symptom: In Cursor,
requires_approvalactions viarun_toolhang ~5 minutes with no approval prompt, then fail closed. Works fine in Claude Code.Root cause (evidence-backed): a Cursor client regression (3.10.20 → 3.12.17), not a plugin/SDK change. Cursor 3.12.x only renders a server-initiated
elicitation/createon its attended tool-call lane.run_toolmarkedreadOnlyHint:trueis classified auto-run/unattended, so the elicitation is silently dropped there. (readOnlyHintis git-constant since Jun 15; the elicitation payload is byte-identical regardless of the annotation; live logs show render on 3.10.20 vs a 300000ms timeout on 3.12.17.)The fix — for Cursor, use Cursor's own native HITL instead of ours
Two paired changes, Cursor-only; Claude Code behavior is unchanged.
readOnlyHintto Cursor (runToolAnnotationsnow takes the client identity). Without the hint, Cursor shows its native run-tool approval before executingrun_tool.!isCursorClientadded to the HITL gate inhandleRunTool). With Cursor's native prompt already gating the call, our elicitation would be a redundant second gate — and it's the one that hangs. So Cursor executes directly after its native approval.Net: Cursor → single native approval prompt; Claude Code → keeps
readOnlyHint+ our elicitation as before.Validation
npm run typecheckclean;npx vitest run189/189, incl. new cases: Cursor gets noreadOnlyHint, and Cursor skips elicitation + executes directly.mainbuild hangs on a write action in Cursor; PR build shows Cursor's native approval and completes.Notes / follow-ups
buildApprovalMessage's Cursor-specific branch is now unreachable (elicitation never fires for Cursor) — harmless; can be cleaned up separately.getClientCapabilities()?.elicitationtruthy, but the SDK'selicitInputneeds.elicitation.form.🤖 Generated with Claude Code